﻿using Core.Entities;
using Core.Enums;
using Core.ObjectOperate;
using Core.ObjectOperate.ReflectionImpl;
using Core.Tools;
using System;
using System.Collections;
using System.Collections.Generic;

namespace Core.ReadWriter
{
    [Serializable]
    public class DefaultInitialization : IReadWriterInitialization
    {
        public BaseReadWriter Initialization(Type Type, object Content, RWSigns Sign)
        {
            Type KeyType;
            Type ValueType;

            if (Type.IsArray)
            {
                if (Content == null)
                {
                    // 在 ListReadWriter 的 Content 属性中会判断 Type 是否为数组。
                    // 如果是数组，则会把 List<> 转换为指定数组类型

                    int Rank = Type.GetArrayRank();

                    if (Rank == 1)
                    {
                        ValueType = Type.GetElementType();

                        Content = new List<object>();
                    }
                    else
                    {
                        // 多维数组为 List<> 的嵌套类型
                        ValueType = typeof(IList);

                        Content = new List<IList>();
                    }
                }
                else
                {
                    // 如果 Content 是一个数组，则创建一个只读的 List 来封装它。
                    var MalContent = new MultidimensionalArrayList((Array)Content);

                    ValueType = MalContent.ElementType;

                    Content = MalContent;
                }

                return new ListReadWriter(Type, Content, ValueType, Sign);
            }
            // 实现 IList<> 的类
            else if (ListReadWriter.TryGetValueType(Type, out ValueType))
            {
                if (Content == null)
                {
                    Content = CreateInstance(Type, Type.IsInterface ?
                        TypeHelper.MakeGenericType(typeof(List<>), ValueType)
                        : null);
                }

                return new ListReadWriter(Type, Content, ValueType, Sign);
            }
            // 实现 IList 的类
            else if (typeof(IList).IsAssignableFrom(Type))
            {
                if (Content == null)
                {
                    Content = CreateInstance(Type, typeof(List<object>));
                }

                return new ListReadWriter(Type, Content, typeof(object), Sign);
            }
            // 实现 IDictionary<,> 的类
            else if (DictionaryReadWriter.TryGetValueType(Type, out KeyType, out ValueType))
            {
                if (Content == null)
                {
                    Content = CreateInstance(Type, Type.IsInterface ?
                        TypeHelper.MakeGenericType(typeof(Dictionary<,>), KeyType, ValueType)
                        : null);
                }

                return new DictionaryReadWriter(Type, Content, KeyType, ValueType, Sign);
            }
            // 实现 IDictionary 的类
            else if (typeof(IDictionary).IsAssignableFrom(Type))
            {
                if (Content == null)
                {
                    Content = CreateInstance(Type, typeof(Dictionary<object, object>));
                }

                return new DictionaryReadWriter(Type, Content, typeof(object), typeof(object), Sign);
            }
            else if (typeof(Table) == Type)
            {
                if (Content == null)
                {
                    Content = new Table();
                }

                return new TableReadWriter(Type, Content, Sign);
            }
            else if (Type.IsInterface)
            {
                throw new ArgumentException("Cannot create instance of interface.");
            }
            else if (Type.IsAbstract)
            {
                throw new ArgumentException("Cannot create instance of abstract class.");
            }
            else if (Content is BaseMultidimensionalArrayList)
            {
                // 多维数组的子元素
                return new ListReadWriter(Type, Content, ((BaseMultidimensionalArrayList)Content).ElementType, Sign);
            }
            else
            {
                IObjectOperater ObjOperater = ObjectOperater.Create(Type
                    , (RWSigns.NonPublic & Sign) != 0);

                if (Content == null)
                {
                    // 通过无参构造函数初始化对象
                    Content = ObjOperater.New();
                }

                return new ObjectReadWriter(Type, Content, ObjOperater, Sign);
            }
        }

        private static object CreateInstance(Type Type, Type DefaultType)
        {
            if (Type.IsInterface)
            {
                if (!Type.IsAssignableFrom(DefaultType))
                {
                    throw new ArgumentException("Cannot create instance of interface.");
                }

                Type = DefaultType;
            }
            else if (Type.IsAbstract)
            {
                throw new ArgumentException("Cannot create instance of abstract class.");
            }

            // 这里对常用的类型进行快速创建

            if (Type == typeof(Dictionary<string, object>))
            {
                return new Dictionary<string, object>();
            }
            if (Type == typeof(Dictionary<object, object>))
            {
                return new Dictionary<object, object>();
            }
            if (Type == typeof(List<object>))
            {
                return new List<object>();
            }

            return Activator.CreateInstance(Type);
        }
    }
}